/*
* ========== Copyright Header Begin ==========================================
* 
* OpenSPARC T1 Processor File: dumpconfig.c
* Copyright (c) 2006 Sun Microsystems, Inc.  All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES.
* 
* The above named program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License version 2 as published by the Free Software Foundation.
* 
* The above named program is distributed in the hope that it will be 
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* General Public License for more details.
* 
* You should have received a copy of the GNU General Public
* License along with this work; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
* 
* ========== Copyright Header End ============================================
*/
#include <sys/types.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <stdarg.h>
#include <time.h>

#include "basics.h"
#include "allocate.h"
#include "simcore.h"
#include "config.h"
#include "options.h"
#include "fileutil.h"
#include "lexer.h"
#include "dumpinfo.h"


dumpinfo_t dumpinfo;

static void dump_system(system_t * sp);
static void dump_domain(domain_t * dp);

	/*
	 * Dump the current config and state of the simulator system
	 */

void dump_config(FILE * outp)
{
	system_t * systemp;
	int i;
	time_t ti;
	struct tm tms;
	char buf[1024];

	ti = time((void*)0);
	localtime_r(&ti, &tms);

	sprintf(buf, "%04d-%02d-%02d %02d:%02d:%02d",
		tms.tm_year+1900, tms.tm_mon+1, tms.tm_mday,
		tms.tm_hour, tms.tm_min, tms.tm_sec);

		/* Wander the systems and dump each one	*/

	dumpinfo.indent = 0;
	dumpinfo.outp = outp;

	pi("\n\
//\n\
// Simulator config/dump file auto-created %s\n\
//\n\n", buf);

	for (i=0; i<target_config.systems.count; i++)
		dump_system(LIST_ENTRY(target_config.systems, i));
}




void dump_system(system_t * sysp)
{
	int i;

	pi("\t// system %d\n", sysp->idx);
	pi("system \"%s\" {\n", sysp->namep);
	dumpinfo.indent ++;

	for (i=0; i<sysp->domains.count; i++)
		dump_domain(LIST_ENTRY(sysp->domains,i));

	dumpinfo.indent --;
	pi("}\n");
}





void dump_domain(domain_t * dp)
{
	int i;
	config_proc_t * procp;
	config_dev_t * devp;

	pi("\t// domain %d\n", dp->idx);
	pi("domain {\n");
	dumpinfo.indent ++;

	pi("sysclkfreq = 0x%llx ;\n", dp->sysclkfreq);

	for (i=0; i<dp->procs.count; i ++) {
		procp = LIST_ENTRY( dp->procs, i );

		procp->proc_typep->dump_proc(dp, procp);
	}

	devp = dp->device.listp;
	if (devp!=(config_dev_t*)0) {
		pi("addressmap {\n");
		dumpinfo.indent++;

		for (i=0; i<dp->device.count; i++) {
				/* leave defn dangling for dump routine */
			pi("\t// device id %d\n", devp->device_id);

			if (devp->is_implied) {
				pi("// ");
				ASSERT(devp->dev_typep->dump_dev == NULL);
			}
			pi("device \"%s\" 0x%llx + 0x%llx %s\n",
				devp->dev_typep->dev_type_namep,
				devp->addrp->baseaddr,
				devp->addrp->topaddr - devp->addrp->baseaddr,
				devp->dev_typep->dump_dev ? "{" : ";" );
			if (devp->dev_typep->dump_dev) {
				devp->dev_typep->dump_dev(devp);
				pi("}\n");
			}
			devp = devp->nextp;
		}

		dumpinfo.indent --;
		pi("}\n");
	}


	dumpinfo.indent --;
	pi("}\n");
}











void pi(char * fmt, ...)
{
	int i;
	va_list args;

	va_start(args, fmt);

	for (i=0; i<dumpinfo.indent; i++)
		fputc('\t', dumpinfo.outp);


	vfprintf(dumpinfo.outp, fmt, args);

	va_end(args);
}

